package com.yfbao.horizon.inspection.prometheus;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PrometheusQueryService {

    @Autowired
    private PrometheusHttpClient prometheusClient;

    @Autowired
    private PromQLBuilder promQLBuilder;


    public MetricsResponseDto testCheckAppIndex(){
        String promQL = "count_over_time((avg_over_time( ( (jvm_memory_used_bytes{area=\"heap\", env='dev'} / jvm_memory_max_bytes{area=\"heap\",  env='dev'}) * 100 > 70 )[5m:1m] ) > 0.7  )[1d:5m])";
        try {
            log.debug("执行PromQL查询: {}", promQL);

            PrometheusResponse response = prometheusClient.executeQuery(promQL);
            MetricsResponseDto prometheusTableDto = parseResponse(response);
            prometheusTableDto.setPromQL(promQL);
            return prometheusTableDto;

        }catch (Exception e){
            log.error("检查堆内存使用率失败", e);
            return MetricsResponseDto.errorResult(e.getMessage());
        }
    }

    /**
     * 查询表格指标数据（单指标阈值判断用）
     * @param promQL
     * @return
     */
    public MetricsResponseDto queryTableMetrics(String promQL){
        try {
            log.debug("执行PromQL查询: {}", promQL);
            PrometheusResponse response = prometheusClient.executeQuery(promQL);
            MetricsResponseDto prometheusTableDto = parseResponse(response);
            prometheusTableDto.setPromQL(promQL);
            return prometheusTableDto;

        }catch (Exception e){
            log.error("查询失败", e);
            return MetricsResponseDto.errorResult(e.getMessage());
        }
    }

    /**
     * 解析prometheus返回信息
     */
    private MetricsResponseDto parseResponse(PrometheusResponse response) {
        MetricsResponseDto result = new MetricsResponseDto();
        result.setSuccess("success".equals(response.getStatus()));

        if (result.isSuccess() && response.getData() != null && response.getData().getResult() != null) {
            List<MetricsDto> details = response.getData().getResult().stream()
                    .map(this::parseResultToDto)
                    .collect(Collectors.toList());
            result.setDetails(details);
            result.setAbnormalCount(details.size());
        } else {
            result.setErrorMsg(response.getError());
        }

        return result;
    }

    /**
     * 解析prometheus返回信息
     */
    private MetricsRangeResponseDto parseRangeResponse(PrometheusResponse response) {
        MetricsRangeResponseDto result = new MetricsRangeResponseDto();
        result.setSuccess("success".equals(response.getStatus()));

        if (result.isSuccess() && response.getData() != null && response.getData().getResult() != null) {
            List<MetricsRangeDto> details = response.getData().getResult().stream()
                    .map(this::parseResultToRangeDto)
                    .collect(Collectors.toList());
            result.setDetails(details);
            result.setAbnormalCount(details.size());
        } else {
            result.setErrorMsg(response.getError());
        }

        return result;
    }



    private MetricsDto parseResultToDto(PrometheusResponse.Result result) {
        MetricsDto detail = new MetricsDto();
        detail.setMetric(result.getMetric());
        detail.setValue(result.getInstantValue());
        detail.setInstance(result.getMetric().get("instance"));
        detail.setJob(result.getMetric().get("job"));
        detail.setApp(result.getMetric().get("app"));
        detail.setEnv(result.getMetric().get("env"));
        detail.setNamespace(result.getMetric().get("kubernetes_namespace"));
        detail.setPodName(result.getMetric().get("kubernetes_pod_name"));
        return detail;
    }

    private MetricsRangeDto parseResultToRangeDto(PrometheusResponse.Result result) {
        MetricsRangeDto detail = new MetricsRangeDto();
        detail.setMetric(result.getMetric());
        List<PrometheusResponse.TimeSeriesPoint> timeSeries = result.getTimeSeries();
        List<MetricValueDto> list = new ArrayList<>();
        for (PrometheusResponse.TimeSeriesPoint timeSery : timeSeries) {
            MetricValueDto metricValueDto = new MetricValueDto();
            metricValueDto.setTimestamp(timeSery.getTimestamp());
            metricValueDto.setValue(timeSery.getValue());
            list.add(metricValueDto);
        }
        list.sort((o1, o2) -> o1.getTimestamp().compareTo(o2.getTimestamp()));
        detail.setValues(list);
        detail.setInstance(result.getMetric().get("instance"));
        detail.setJob(result.getMetric().get("job"));
        detail.setApp(result.getMetric().get("app"));
        detail.setEnv(result.getMetric().get("env"));
        detail.setNamespace(result.getMetric().get("kubernetes_namespace"));
        detail.setPodName(result.getMetric().get("kubernetes_pod_name"));
        return detail;
    }

    /**
     * 执行自定义PromQL查询
     */
    public PrometheusResponse executeCustomQuery(String customPromQL) throws IOException {
        return prometheusClient.executeQuery(customPromQL);
    }


    /**
     * 查询表格指标数据（单指标阈值判断用）
     * @param promQL
     * @return
     */
    public MetricsRangeResponseDto queryMetricsByRange(String promQL, long start, long end, String step){
        try {
            log.debug("执行PromQL查询: {}", promQL);
            PrometheusResponse response = prometheusClient.executeRangeQuery(promQL, start, end, step);
            MetricsRangeResponseDto metricsRangeResponseDto = parseRangeResponse(response);
            metricsRangeResponseDto.setPromQL(promQL);
            metricsRangeResponseDto.setStart(start);
            metricsRangeResponseDto.setEnd(end);
            metricsRangeResponseDto.setStep(step);
            return metricsRangeResponseDto;

        }catch (Exception e){
            log.error("查询失败", e);
            return MetricsRangeResponseDto.errorResult(e.getMessage());
        }
    }


}
